package com.threadPool.enums;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 拒绝策略枚举类（包含五种常见策略）
 */
public enum RejectedPolicy implements RejectedExecutionHandler {
    /**
     * 直接抛出异常
     */
    ABORT {
        @Override
        public void rejected(Runnable task, BlockingQueue<Runnable> taskQueue, AtomicInteger poolSize) {
            logger.error("Task " + task + " rejected from " + this);
        }
    },

    /**
     * 调用者线程直接执行任务
     */
    CALLER_RUNS {
        @Override
        public void rejected(Runnable task, BlockingQueue<Runnable> taskQueue, AtomicInteger poolSize) {
            if (!Thread.currentThread().isInterrupted()) {
                task.run();  // 由提交任务的线程直接执行
            }
        }
    },

    /**
     * 静默丢弃新任务
     */
    DISCARD {
        @Override
        public void rejected(Runnable task, BlockingQueue<Runnable> taskQueue, AtomicInteger poolSize) {
            // 不做任何处理，直接丢弃
        }
    },

    /**
     * 丢弃队列中最旧的任务后重试提交
     */
    DISCARD_OLDEST {
        @Override
        public void rejected(Runnable task, BlockingQueue<Runnable> taskQueue, AtomicInteger poolSize) {
            if (!taskQueue.isEmpty()) {
                taskQueue.poll();  // 丢弃队列头部的旧任务
                taskQueue.offer(task);  // 尝试重新提交新任务
            }
        }
    },

    /**
     * 自定义策略（示例：记录日志后丢弃）
     */
    CUSTOM {
        @Override
        public void rejected(Runnable task, BlockingQueue<Runnable> taskQueue, AtomicInteger poolSize) {
            logger.error("Custom policy: Task " + task + " rejected");
            // 这里可以扩展其他逻辑（如持久化、重试等）
        }
    };

    /**
     * 统一的策略接口方法
     * @param task      被拒绝的任务
     * @param taskQueue 任务队列
     * @param poolSize  当前线程池中的线程数（可根据需要扩展参数）
     */
    @Override
    public abstract void rejected(Runnable task, BlockingQueue<Runnable> taskQueue, AtomicInteger poolSize);

    private static final Logger logger = LoggerFactory.getLogger(RejectedPolicy.class);
}

/**
 * 策略接口（与JDK的RejectedExecutionHandler兼容）
 */
interface RejectedExecutionHandler {
    void rejected(Runnable task, BlockingQueue<Runnable> taskQueue, AtomicInteger poolSize);
}